package tool.zyk.spring.bean;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import tool.zyk.spring.annotation.EnableRpc;
import tool.zyk.spring.invoke.SpringReflectExecutor;

/**
 * @author feite.zyk
 * @time 2024/2/2 15:18
 * @description
 */
@Slf4j
public class RpcInjectRegister implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
        AnnotationAttributes mapperScanAttrs = AnnotationAttributes
                .fromMap(importingClassMetadata.getAnnotationAttributes(EnableRpc.class.getName()));

        // auto injector
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ConsumerAutoInjector.class);
        AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
        String beanName = importBeanNameGenerator.generateBeanName(beanDefinition, registry);
        registry.registerBeanDefinition(beanName, beanDefinition);

        // beanFactory
        BeanDefinitionBuilder factorBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(RpcInjector.class);
        if (mapperScanAttrs != null) {
            String basePackage = mapperScanAttrs.get("value").toString();
            factorBeanDefinition.addPropertyValue("basePackage", basePackage);
            AbstractBeanDefinition factorBeanDefinitionBeanDefinition = factorBeanDefinition.getBeanDefinition();
            registry.registerBeanDefinition(importBeanNameGenerator.generateBeanName(factorBeanDefinitionBeanDefinition, registry), factorBeanDefinitionBeanDefinition);
        }

        if (mapperScanAttrs != null) {
            boolean isServer = (boolean) mapperScanAttrs.get("isServer");
            if (isServer) {
                BeanDefinitionBuilder serverBeanBuilder = BeanDefinitionBuilder.genericBeanDefinition(ServerBean.class);
                AbstractBeanDefinition serverBeanBuilderBeanDefinition = serverBeanBuilder.getBeanDefinition();
                registry.registerBeanDefinition(importBeanNameGenerator.generateBeanName(serverBeanBuilderBeanDefinition, registry), serverBeanBuilderBeanDefinition);


                BeanDefinitionBuilder serviceProxyBuilder = BeanDefinitionBuilder.genericBeanDefinition(SpringReflectExecutor.class);
                AbstractBeanDefinition serviceProxyBuilderBeanDefinition = serviceProxyBuilder.getBeanDefinition();
                registry.registerBeanDefinition(importBeanNameGenerator.generateBeanName(serviceProxyBuilderBeanDefinition, registry), serviceProxyBuilderBeanDefinition);
            }
        }


    }

}
